<template>
	<picker mode="multiSelector" :range="addressRange" range-key="name" @change="pickerChange"
		@columnchange="columnchange" :value="value" @cancel="$emit('cancel')" :disabled="disabled">
		<slot></slot>
	</picker>
</template>

<script>
	import address from "../../utils/address.json";
	export default {
		/**
		 * @param modelValue Array(string) ['四川省', '成都市', '武侯区']
		 * @param codeValue Array(string | number) [ "51","5101", "510107" ]
		 * @param selectIndex Array(number) [ 0, 0, 0 ]
		 * @param disabled 禁用
		 */
		props: {
			modelValue: Array,
			codeValue: Array,
			disabled: {
				type: Boolean,
				default: false,
			},
			selectIndex: {
				type: Array,
				default: () => [0, 0, 0],
			},
		},

		emits: [
			"update:modelValue",
			"update:codeValue",
			"columnchange",
			"change",
			"cancel",
		],
		data() {
			return {
				addressRange: [],
				value: [0, 0, 0],
			};
		},
		created() {
			this.value = [...this.selectIndex];
			this.addressRange[0] = address;
			this.setDefByCode();
			this.setDefByName();
		},
		watch: {
			modelValue() {
				this.setDefByName();
			},
			codeValue() {
				this.setDefByCode();
			},
		},
		methods: {
			columnchange(e) {
				const {
					column,
					value
				} = e.detail;
				this.$emit("columnchange", e.detail);
				if (column === 0) {
					this.addressRange[1] = this.addressRange[0][value].child;
					this.addressRange[2] = this.addressRange[1][this.value[1]]?.child || this.addressRange[1][0].child;
				}
				if (column === 1) {
					this.addressRange[2] = this.addressRange[1][value].child;
				}
			},
			pickerChange(e) {
				const v = e.detail.value;
				const {
					name: province
				} = this.addressRange[0][v[0]];
				const {
					name: city
				} = this.addressRange[1][v[1]];
				const {
					code: areaCode,
					name: area,
					cityCode,
					provinceCode,
				} = this.addressRange[2][v[2]];
				this.$emit("change", {
					areaCode,
					area,
					cityCode,
					provinceCode,
					province,
					city,
				});
				this.$emit("update:modelValue", [province, city, area]);
				this.$emit("update:codeValue", [provinceCode, cityCode, areaCode]);
			},
			setDefByCode() {
				if (this.codeValue instanceof Array && this.codeValue.length >= 1) {
					const provinceIndex = this.addressRange[0].findIndex(
						(item) => item.code === this.codeValue[0].toString()
					);
					if (provinceIndex === -1) {
						this.addressRange[1] = this.addressRange[0][0].child;
						this.addressRange[2] = this.addressRange[1][0].child;
						return;
					}
					this.addressRange[1] = this.addressRange[0][provinceIndex].child;

					const cityIndex = this.addressRange[1].findIndex(
						(item) => item.code === this.codeValue[1]?.toString()
					);
					if (cityIndex === -1) {
						this.addressRange[2] = this.addressRange[1][0].child;
						this.$nextTick(() => {
							this.value = [provinceIndex, 0, 0];
						});
						return;
					}
					this.addressRange[2] = this.addressRange[1][cityIndex].child;

					const areaIndex = this.addressRange[2].findIndex(
						(item) => item.code === this.codeValue[2]?.toString()
					);
					if (areaIndex === -1) {
						this.$nextTick(() => {
							this.value = [provinceIndex, cityIndex, 0];
						});
						return;
					}
					this.$nextTick(() => {
						this.value = [provinceIndex, cityIndex, areaIndex];
					});
				} else {
					this.addressRange[1] = this.addressRange[0][0].child;
					this.addressRange[2] = this.addressRange[1][0].child;
				}
			},
			setDefByName() {
				if (this.modelValue instanceof Array && this.modelValue.length >= 1) {
					const provinceIndex = this.addressRange[0].findIndex(
						(item) => item.name === this.modelValue[0]
					);
					if (provinceIndex === -1) {
						this.addressRange[1] = this.addressRange[0][0].child;
						this.addressRange[2] = this.addressRange[1][0].child;
						return;
					}
					this.addressRange[1] = this.addressRange[0][provinceIndex].child;

					const cityIndex = this.addressRange[1].findIndex(
						(item) => item.name === this.modelValue[1]
					);
					if (cityIndex === -1) {
						this.addressRange[2] = this.addressRange[1][0].child;
						this.$nextTick(() => {
							this.value = [provinceIndex, 0, 0];
						});
						return;
					}
					this.addressRange[2] = this.addressRange[1][cityIndex].child;

					const areaIndex = this.addressRange[2].findIndex(
						(item) => item.name === this.modelValue[2]
					);
					if (areaIndex === -1) {
						this.$nextTick(() => {
							this.value = [provinceIndex, cityIndex, 0];
						});
						return;
					}
					this.$nextTick(() => {
						this.value = [provinceIndex, cityIndex, areaIndex];
					});
				} else {
					this.addressRange[1] = this.addressRange[0][0].child;
					this.addressRange[2] = this.addressRange[1][0].child;
				}
			},
		},
	};
</script>